<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article# " lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>kivy-ch9 | 绿萝间</title>
<link href="../assets/css/all-nocdn.css" rel="stylesheet" type="text/css">
<link href="../assets/css/ipython.min.css" rel="stylesheet" type="text/css">
<link href="../assets/css/nikola_ipython.css" rel="stylesheet" type="text/css">
<meta name="theme-color" content="#5670d4">
<meta name="generator" content="Nikola (getnikola.com)">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<link rel="canonical" href="https://muxuezi.github.io/posts/kivy-ch9.html">
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"] ],
        displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
        processEscapes: true
    },
    displayAlign: 'center', // Change this to 'center' to center equations.
    "HTML-CSS": {
        styles: {'.MathJax_Display': {"margin": 0}}
    }
});
</script><!--[if lt IE 9]><script src="../assets/js/html5.js"></script><![endif]--><meta name="author" content="Tao Junjie">
<link rel="prev" href="3-feature-extraction-and-preprocessing.html" title="3-feature-extraction-and-preprocessing" type="text/html">
<link rel="next" href="frequentism-and-bayesianism-chs.html" title="frequentism-and-bayesianism-chs" type="text/html">
<meta property="og:site_name" content="绿萝间">
<meta property="og:title" content="kivy-ch9">
<meta property="og:url" content="https://muxuezi.github.io/posts/kivy-ch9.html">
<meta property="og:description" content="射击app¶前面提到过，在这一章我们来做射击（shoot-em-up，简写shmup）app，一个快节奏的射击游戏，比魂斗罗简单许多。



做一个在屏幕上同时移动不同内容的游戏，需要大量的渲染来实现，在移动端（或多平台支持）也是如此。这一章我们就来做这些事情，上一章的知识和源代码已经带我们入了门。
教学大纲如下：

用Kivy的纹理图集（Texture atlases）完成本来需要用底层代码实现">
<meta property="og:type" content="article">
<meta property="article:published_time" content="2015-06-24T13:43:47+08:00">
<meta property="article:tag" content="CHS">
<meta property="article:tag" content="ipython">
<meta property="article:tag" content="Kivy">
<meta property="article:tag" content="Python">
</head>
<body>
<a href="#content" class="sr-only sr-only-focusable">Skip to main content</a>

<!-- Menubar -->

<nav class="navbar navbar-inverse navbar-static-top"><div class="container">
<!-- This keeps the margins nice -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-navbar" aria-controls="bs-navbar" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="https://muxuezi.github.io/">

                <span id="blog-title">绿萝间</span>
            </a>
        </div>
<!-- /.navbar-header -->
        <div class="collapse navbar-collapse" id="bs-navbar" aria-expanded="false">
            <ul class="nav navbar-nav">
<li>
<a href="../archive.html">Archive</a>
                </li>
<li>
<a href="../categories/">Tags</a>
                </li>
<li>
<a href="../rss.xml">RSS feed</a>

                
            </li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
    <a href="kivy-ch9.ipynb" id="sourcelink">Source</a>
    </li>

                
            </ul>
</div>
<!-- /.navbar-collapse -->
    </div>
<!-- /.container -->
</nav><!-- End of Menubar --><div class="container" id="content" role="main">
    <div class="body-content">
        <!--Body content-->
        <div class="row">
            
            
<article class="post-text h-entry hentry postpage" itemscope="itemscope" itemtype="http://schema.org/Article"><header><h1 class="p-name entry-title" itemprop="headline name"><a href="#" class="u-url">kivy-ch9</a></h1>

        <div class="metadata">
            <p class="byline author vcard"><span class="byline-name fn">
                    Tao Junjie
            </span></p>
            <p class="dateline"><a href="#" rel="bookmark"><time class="published dt-published" datetime="2015-06-24T13:43:47+08:00" itemprop="datePublished" title="2015-06-24 13:43">2015-06-24 13:43</time></a></p>
            
        <p class="sourceline"><a href="kivy-ch9.ipynb" id="sourcelink">Source</a></p>

        </div>
        

    </header><div class="e-content entry-content" itemprop="articleBody text">
    <div tabindex="-1" id="notebook" class="border-box-sizing">
    <div class="container" id="notebook-container">

<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="射击app">射击app<a class="anchor-link" href="kivy-ch9.html#%E5%B0%84%E5%87%BBapp">¶</a>
</h2>
<p>前面提到过，在这一章我们来做射击（shoot-em-up，简写shmup）app，一个快节奏的射击游戏，比魂斗罗简单许多。</p>
<!-- TEASER_END-->

<p><img src="kbpic/9.1%20shmup.png" alt="shmup"></p>
<p>做一个在屏幕上同时移动不同内容的游戏，需要大量的渲染来实现，在移动端（或多平台支持）也是如此。这一章我们就来做这些事情，上一章的知识和源代码已经带我们入了门。</p>
<p>教学大纲如下：</p>
<ul>
<li>用Kivy的纹理图集（Texture atlases）完成本来需要用底层代码实现的纹理坐标值的设置工作</li>
<li>继续用GLSL开发一个质点原型，然后用这个原型做不同的游戏角色</li>
<li>实现二维射击游戏的——一个控件，鼠标和触摸屏，基本冲突发现子弹</li>
</ul>
<p>后面会涉及到大量细节，如果看不明白就运行一下文末的源代码。</p>
<h3 id="项目的限制">项目的限制<a class="anchor-link" href="kivy-ch9.html#%E9%A1%B9%E7%9B%AE%E7%9A%84%E9%99%90%E5%88%B6">¶</a>
</h3>
<p>我们做的app比较简单，功能有限，至少有以下限制：</p>
<ul>
<li>为了简化，忽略了奖惩机制，2048里面也是这样</li>
<li>这个游戏只有一个敌人角色，简单模式</li>
<li>许多优化被忽略了，可以少写一些代码</li>
</ul>
<p>如果感兴趣可以自己做。下面我们来看一下Kivy的纹理处理相关内容，后面会用到。</p>
<h3 id="纹理图集简介">纹理图集简介<a class="anchor-link" href="kivy-ch9.html#%E7%BA%B9%E7%90%86%E5%9B%BE%E9%9B%86%E7%AE%80%E4%BB%8B">¶</a>
</h3>
<p>纹理图集（也叫sprite sheets）是一种应用开发中把图象组合成更大纹理的方法。与只是把一堆单个图象载入应用相比，这么做有些好处：</p>
<ul>
<li>应用打开更快，读一个大文件比读许多小文件要快。如果你有几百个这样的图片，用这种方法性能提升会很明显——网页上更是如此：图片太多会严重占用HTTP请求资源，在移动设备上这点更加明显</li>
<li>一次性渲染也会很更快。用纹理映射可以只改变需要变化的纹理坐标，而不需要引起其他内容的变化</li>
<li>当有一个大的模型时，像GLSL类的渲染，用纹理图集方法更适合。另外，纹理的坐标值更容易获取，也不需要二次绑定纹理</li>
</ul>
<blockquote>
<p>在HTML和CSS里面常用类似的方法，叫CSS图片合并（CSS sprites）。原理是一样的。网页app通常是获取网络资源，如果大量图片存在会占用HTTP请求数，用CSS图片合并可以很好的降低HTTP请求占用。</p>
</blockquote>
<p>这一章，我们要介绍以下内容：</p>
<ul>
<li>用Kivy的CLI工具创建纹理映射</li>
<li>文件格式化和<code>.atlas</code>文件结构</li>
<li>Kivy应用纹理图集的用法</li>
</ul>
<p>如果你已经掌握了相关内容，可以直接跳到<em>GLSL使用纹理图集</em>一节。</p>
<h4 id="创建一个图集">创建一个图集<a class="anchor-link" href="kivy-ch9.html#%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%9B%BE%E9%9B%86">¶</a>
</h4>
<p>和网页开发不同，那里没有标准工具处理这个任务，Kivy框架用一个命令行工具处理图集映射。</p>
<div class="highlight"><pre><span></span>python –m kivy.atlas &lt;atlas_name&gt; &lt;texture_size&gt; &lt;images…&gt;
</pre></div>
<p>在Mac系统上，把<code>python</code>替换成<code>kivy</code>，因为安装的时候<code>Kivy.app</code>会调用Python解释器。</p>
<p>这样会创建至少两个文件，由所有的图像是否满足一个设定大小的纹理来决定。本章假设<code>texture_size</code>的值足够包含所有图像。</p>
<p>所有输出文件都是<code>atlas_name</code>开头的参数：</p>
<p>-</p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [ ]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span> 
</pre></div>

</div>
</div>
</div>

</div>
<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p><a href="kbpic/src/9_ShootEmUp/">源代码</a></p>

</div>
</div>
</div>
    </div>
  </div>

    </div>
    <aside class="postpromonav"><nav><ul itemprop="keywords" class="tags">
<li><a class="tag p-category" href="../categories/chs.html" rel="tag">CHS</a></li>
            <li><a class="tag p-category" href="../categories/ipython.html" rel="tag">ipython</a></li>
            <li><a class="tag p-category" href="../categories/kivy.html" rel="tag">Kivy</a></li>
            <li><a class="tag p-category" href="../categories/python.html" rel="tag">Python</a></li>
        </ul>
<ul class="pager hidden-print">
<li class="previous">
                <a href="3-feature-extraction-and-preprocessing.html" rel="prev" title="3-feature-extraction-and-preprocessing">Previous post</a>
            </li>
            <li class="next">
                <a href="frequentism-and-bayesianism-chs.html" rel="next" title="frequentism-and-bayesianism-chs">Next post</a>
            </li>
        </ul></nav></aside><script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> </script><script type="text/x-mathjax-config">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"] ],
        displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
        processEscapes: true
    },
    displayAlign: 'center', // Change this to 'center' to center equations.
    "HTML-CSS": {
        styles: {'.MathJax_Display': {"margin": 0}}
    }
});
</script></article>
</div>
        <!--End of body content-->

        <footer id="footer">
            Contents © 2017         <a href="mailto:muxuezi@gmail.com">Tao Junjie</a> - Powered by         <a href="https://getnikola.com" rel="nofollow">Nikola</a>         
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0">
<img alt="Creative Commons License BY-NC-SA" style="border-width:0; margin-bottom:12px;" src="http://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png"></a>
            
        </footer>
</div>
</div>


            <script src="../assets/js/all-nocdn.js"></script><script>$('a.image-reference:not(.islink) img:not(.islink)').parent().colorbox({rel:"gal",maxWidth:"100%",maxHeight:"100%",scalePhotos:true});</script><!-- fancy dates --><script>
    moment.locale("en");
    fancydates(0, "YYYY-MM-DD HH:mm");
    </script><!-- end fancy dates --><script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-51330059-1', 'auto');
  ga('send', 'pageview');

</script>
</body>
</html>
